﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Input;
using System.IO;

namespace PSE.Deployment.ConfigurationManager.Controls.Validations
{
    public enum ErrorMessage
    {
        [Description("O valor informado não é um número")]
        NaN = 1,
        
        [Description("Por favor digite uma URL válida")]
        InvalidURL = 2,
        
        [Description("Formato da hora incorreto")]
        InvalidTime = 3,
        
        [Description("Campo obrigatório")]
        RequiredField = 4,

        [Description("Arquivo não encontrado")]
        InvalidFilePath = 5,

        [Description("Pasta não encontrada")]
        InvalidFolderPath = 6
    }

    /// <summary>
    /// Classe que possui validação dos controles Int32Texbox, TimeTextBox, UrlTextBox
    /// </summary>
    public static class SpecializedControlsValidations
    {
        static List<Key> _allowedEditingKeys = new List<Key> { Key.Back, Key.Tab, Key.Up, Key.Down, Key.Left, Key.Right, Key.Delete, Key.Home, Key.End, Key.CapsLock };
        static List<Key> _allowedNumberKeys = new List<Key> { Key.D0, Key.D1, Key.D2, Key.D3, Key.D4, Key.D5, Key.D6, Key.D7, Key.D8, Key.D9, Key.NumPad0, Key.NumPad1, Key.NumPad2, Key.NumPad3, Key.NumPad4, Key.NumPad5, Key.NumPad6, Key.NumPad7, Key.NumPad8, Key.NumPad9 };
        static List<Key> _allowedCtrlModifierKeys = new List<Key> { Key.A, Key.C, Key.V, Key.X, Key.Z };
        static List<Key> _allowedShiftModifierKeys = new List<Key> { Key.Left, Key.Right, Key.End, Key.Home, Key.Delete, Key.Tab };
        public static bool AllowedModifiers(Key key)
        {
            if ((Keyboard.Modifiers == ModifierKeys.Control && _allowedCtrlModifierKeys.Contains(key)))
                return true;
            else if ((Keyboard.Modifiers == ModifierKeys.Shift && _allowedShiftModifierKeys.Contains(key)))
                return true;

            return false;
        }

        public static bool IsNumber(Key key, bool warnOnError)
        {
            if (Keyboard.Modifiers == ModifierKeys.None && (_allowedEditingKeys.Contains(key) || _allowedNumberKeys.Contains(key)))
                return true;
            else if (AllowedModifiers(key))
                return true;
            else
            {
                if (warnOnError)
                    ShowError(ErrorMessage.NaN);
            }

            return false;
        }

        public static bool IsNumber(string text, bool warnOnError)
        {
            if (!String.IsNullOrEmpty(text))
            {
                try
                {
                    Int32.Parse(text);
                    return true;
                }
                catch
                {
                    if (warnOnError)
                        ShowError(ErrorMessage.NaN);

                    return false;
                }
            }

            return false;
        }

        public static bool IsURL(string text, bool warnOnError)
        {
            if (!String.IsNullOrEmpty(text))
            {
                //string regex = "^(https?://)"
                //+ "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //user@
                //+ @"(([0-9]{1,3}\.){3}[0-9]{1,3}" //IP
                //+ "|" // permite IP ou dominio
                //+ @"([0-9a-z_!~*'()-]+\.)*" // dominios de terceiros - www
                //+ @"([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // dominio de segundo nivel
                //+ "[a-z]{2,6})" // dominios de primeiro nivel  - .com or .museum
                //+ "(:[0-9]{1,4})?" // numero da porta - :80 
                //+ "((/?)|" // barra nao eh necessaria caso nao haja nome de arquivo
                //+ "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
                //Regex r = new Regex(regex);

                //if (r.IsMatch(text))

                if (Uri.IsWellFormedUriString(text, UriKind.Absolute))
                    return true;
                else
                {
                    if (warnOnError)
                        ShowError(ErrorMessage.InvalidURL);
                    return false;
                }
            }
            return true;
        }

        public static bool IsEmpty(string text, bool warnOnError)
        {
            if (String.IsNullOrEmpty(text))
            {
                if (warnOnError)
                    ShowError(ErrorMessage.RequiredField);

                return true;
            }
            return false;
        }

        public static bool IsTime(string text, bool warnOnError)
        {
            if (!String.IsNullOrEmpty(text))
            {
                Regex r = new Regex(@"^([01]\d|2[0-3])(:[0-5]\d){2,2}$");

                if (r.IsMatch(text))
                    return true;
                else
                {
                    if (warnOnError)
                        ShowError(ErrorMessage.InvalidTime);
                    return false;
                }
            }
            return true;
        }

        public static bool IsFilePath(string text, bool warnOnError)
        {
            if (!String.IsNullOrEmpty(text))
            {
                if (File.Exists(text))
                    return true;
                else
                {
                    if (warnOnError)
                        ShowError(ErrorMessage.InvalidFilePath);
                    return false;
                }
            }
            return true;
        }

        public static bool IsFolderPath(string text, bool warnOnError)
        {
            if (!String.IsNullOrEmpty(text))
            {
                if (Directory.Exists(text))
                    return true;
                else
                {
                    if (warnOnError)
                        ShowError(ErrorMessage.InvalidFolderPath);
                    return false;
                }
            }
            return true;
        }

        public static string GetDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
        }

        public static void ShowError(ErrorMessage msg)
        {
            ConfigurationMessageBox.Show(GetDescription(msg), "Aviso", ConfigurationMessageBoxButton.Ok, ConfigurationMessageBoxImage.Exclamation);
        }
    }
}